package com.yida.gwj.common.utils;

import org.apache.commons.collections.CollectionUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * 比较两个集合是否相等
 *
 * @author wkz
 * @date 2023/04/11
 */
public class CheckDiffList {
    /**
     * 方法一：使用contains()进行比较 注意：当集合里有重复元素时，此方法不可行
     *
     * @param list
     * @param list1
     * @return
     */
    public static boolean checkDifferent(List<String> list, List<String> list1) {
        // long startTime = System.nanoTime();
        if (list == null && list1 == null) {
            return true;
        } else if (list == null || list1 == null) {
            return false;
        }
        if (list.size() != list1.size()) {
            // System.out.println("spare time:" + (System.nanoTime() - startTime));
            return false;
        }
        if (list.containsAll(list1) && list1.containsAll(list)) {
            // System.out.println("spare time:" + (System.nanoTime() - startTime));
            return true;
        }
        // System.out.println("spare time:" + (System.nanoTime() - startTime));
        return false;
    }

    /**
     * 方法二：使用apache common工具类
     *
     * @param list
     * @param list1
     * @return
     */
    public static boolean checkDifferent2(List<String> list, List<String> list1) {
        long startTime = System.nanoTime();
        boolean isEqual;
        if (list == null && list1 == null) {
            isEqual = true;
        } else if (list == null || list1 == null) {
            isEqual = false;
        } else {
            isEqual = CollectionUtils.isEqualCollection(list, list1);
        }
        System.out.println("spare time:" + (System.nanoTime() - startTime));
        return isEqual;
    }

    /**
     * 方法三：如果业务要求两个list的顺序一致，内容一致，直接使用equals()方法
     *
     * @param list
     * @param list1
     * @return
     */
    public static boolean checkDifferent3(List<String> list, List<String> list1) {
        boolean isEqual;
        if (list == null && list1 == null) {
            isEqual = true;
        } else if (list == null || list1 == null) {
            isEqual = false;
        } else {
            isEqual = list.equals(list1);
        }
        return isEqual;
    }

    /**
     * 方法四：将集合排序后进行比较
     *
     * @param list
     * @param list1
     */
    public static boolean checkDifferent4(List<String> list, List<String> list1) {
        long startTime = System.nanoTime();
        if (list == null && list1 == null) {
            return true;
        } else if (list == null || list1 == null) {
            return false;
        }
        if (list.size() != list1.size()) {
            System.out.println("spare time:" + (System.nanoTime() - startTime));
            return false;
        }
        Collections.sort(list);
        Collections.sort(list1);
        boolean isEqual = list1.equals(list);
        System.out.println("spare time:" + (System.nanoTime() - startTime));
        return isEqual;
    }

    /**
     * 方法四：将集合排序,然后转为String后进行比较，效率更高
     *
     * @param list
     * @param list1
     */
    public static boolean checkDifferent5(List<String> list, List<String> list1) {
        long startTime = System.nanoTime();
        if (list == null && list1 == null) {
            return true;
        } else if (list == null || list1 == null) {
            return false;
        }
        if (list.size() != list1.size()) {
            return false;
        }
        Collections.sort(list);
        Collections.sort(list1);
        boolean isEqual = list1.toString().equals(list.toString());
        System.out.println("spare time:" + (System.nanoTime() - startTime));
        return isEqual;
    }

    /**
     * 按某个指定字段去重
     *
     * @param keyExtractor 需要去重的字段
     * @return java.util.function.Predicate<T>
     * @author 陈賝
     * @date 2022/9/2 13:49
     */
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        List<String> list1 = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            list.add("test" + i);
            list1.add("test" + (i * 2));
        }
        String[] arr = {"1", "2", "2"};
        String[] arr1 = {"1", "1", "2"};
        list = Arrays.asList(arr);
        list1 = Arrays.asList(arr1);
        System.out.println(checkDifferent(list, list1));
        System.out.println(checkDifferent2(list, list1));
        System.out.println(checkDifferent3(list, list1));
        System.out.println(checkDifferent4(list, list1));
        System.out.println(checkDifferent5(list, list1));
    }
}
